#include "C_Widget.h"

using namespace gui;

/////////////////////////////////////////////////////////////////////////////////////////////
//	CONSTRUCTOR
/////////////////////////////////////////////////////////////////////////////////////////////
C_Widget::C_Widget(C_Widget* parent)
: m_pos							(0.0f, 0.0f)
, m_aPos						(0.0f, 0.0f)
, m_size						(200.0f, 50.0f)
, m_backgroundColor				(0.5f, 0.5f, 0.5f, 1.0f)
, m_borderColor					(1.0f, 0.0f, 0.0f, 1.0f)
, m_margin						(4.0f, 4.0f, 4.0f, 4.0f)
, m_padding						(4.0f)
, m_visible						(true)
, m_background					(true)
, m_border						(true)
, m_focus						(false)
, m_is_mouseOver				(false)
, m_is_mouseButtonPress			(false)
, m_is_mouseButtonClick			(false)
{
	m_parent = parent;
	m_coordType		= COORD_TYPE_RELATIVE;
	m_containerType = CONTAINER_VERTICAL;
	m_vAlign		= GRID_TOP;
	m_hAlign		= GRID_LEFT;

	if (m_parent != NULL)
	{
		m_aPos = m_parent->m_aPos;
	}
	else
	{
		m_aPos = m_pos;
	}
#ifndef GUI_DEBUG
	setBorderVisible(false);
	setBackgroundVisible(false);
#endif
}

/////////////////////////////////////////////////////////////////////////////////////////////
//	DESTRUCTOR
/////////////////////////////////////////////////////////////////////////////////////////////
C_Widget::~C_Widget()
{
}

/////////////////////////////////////////////////////////////////////////////////////////////
//	HANDLE EVENTS
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::handleEvent(sf::Event e)
{
	VC_Drawable::handleEvent(e);

	switch (e.type)
	{
	case sf::Event::MouseMoved:
	{
								  if (mouseX() >= m_aPos.x && mouseX() <= m_aPos.x+m_size.x &&
									  mouseY() >= m_aPos.y && mouseY() <= m_aPos.y+m_size.y)
								  {
									  m_is_mouseOver = true;
								  }
								  else
								  {
									  m_is_mouseOver = false;
								  }
								  break;
	}
	case sf::Event::MouseButtonReleased:
	{
										   if (m_is_mouseOver)
										   {
											   onClickButton(e.mouseButton.button);
											   onReleaseButton(e.mouseButton.button);
											   m_is_mouseButtonClick = true;
											   m_focus = true;
										   }

										   m_is_mouseButtonPress = false;
										   break;
	}
	case sf::Event::MouseButtonPressed:
	{
										   if (m_is_mouseOver)
										   {
											   onPressButton(e.mouseButton.button);
											   m_is_mouseButtonPress = true;
											   m_mouseButton = e.mouseButton.button;
										   }
										   break;
	}
	default:
		break;
	}
	FOR_VEC_I(it, m_children, C_Widget*)
	{
		(*it)->handleEvent(e);
	}

}


/////////////////////////////////////////////////////////////////////////////////////////////
//	RENDER
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::render()
{
	/*
	Exit function, all children too exit render
	*/
	if (m_visible == false) return;

	GLfloat vertex[] =
	{
		0.0f, 0.0f,
		0.0f, m_size.y,
		m_size.x, 0.0f,
		m_size.x, m_size.y
	};

	GLuint backgroundIndex[] =
	{
		0, 1, 2, 3
	};

	GLuint borderIndex[] =
	{
		0, 2, 3, 1
	};

	glPushMatrix();

	if (m_parent == NULL)
	{
		glTranslatef(m_pos.x, m_pos.y, 0.0f);
	}
	else if (m_coordType == COORD_TYPE_ABSOLUTE)
	{
		glTranslatef(m_pos.x, m_pos.y, 0.0f);
	}
	else
	{
		glTranslatef(m_aPos.x, m_aPos.y, 0.0f);
	}

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_INDEX_ARRAY);

		glColor4f(
				m_backgroundColor.r,
				m_backgroundColor.g,
				m_backgroundColor.b,
				m_backgroundColor.a
		);

		//load vertex
		glVertexPointer(2, GL_FLOAT, 0, vertex);

		/////////////////////////////////////////////////////////
		////////// DRAW BACKGROUND
		if (m_background)
			glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, backgroundIndex);

		glColor4f(
			m_borderColor.r,
			m_borderColor.g,
			m_borderColor.b,
			m_borderColor.a
			);
		/////////////////////////////////////////////////////////
		////////// DRAW BORDER
		if (m_border)
		{
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
			glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, borderIndex);
			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
		}

	glDisableClientState(GL_INDEX_ARRAY);
	glDisableClientState(GL_VERTEX_ARRAY);

	///////////////////////////////////////////////////////////////////////////////////
	////////////////////	RENDER WIDGETS
	renderWidget();

	glPopMatrix();

	/////////////////////////////////////////////////////////////////////////////////////
	///////////////////	RENDER CHILDREN
	FOR_VEC_I(it, m_children, C_Widget*)
	{
		(*it)->render();
	}
	m_is_mouseButtonClick = false;
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	UPDATE
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::update()
{

}


/////////////////////////////////////////////////////////////////////////////////////////////
//	RENDER WIDGET FOR VIRTUAL
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::renderWidget()
{
	//////////////////////////////////////////////////////////////////////////////////
	//////////////	RENDERING OTHER WIDGETS
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	ADD WIDGET
/////////////////////////////////////////////////////////////////////////////////////////////
C_Widget* C_Widget::addWidget(C_Widget* widget, E_CoordType type)
{
	EX_R(widget == NULL, "NULL pointer on widget!");

	widget->setCoordType(type);
	widget->setParent(this);
	m_children.push_back(widget);

	updateX(); updateY();
	syncWidgets();
	return widget;
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	SET VERTICAL ALIGN
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::setVerticalAlign(E_GridAlignVertical align)
{ 
	m_vAlign = align; 
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	SET HORIZONTAL ALIGN
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::setHorizontalAlign(E_GridAlignHorizontal align)
{ 
	m_hAlign = align; 
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	SET COORDINATE TYPE
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::setCoordType(E_CoordType type)
{ 
	m_coordType = type; 

	if (type == COORD_TYPE_GRID)
	{
	}
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	ALL CHILDREN UPDATE X
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::updateX()
{
	if (m_containerType == CONTAINER_VERTICAL)
	{
		float width = m_margin.r + getMaxWidgetWidth() + m_margin.g; //add left margin + width + right margin
		if (this->size().x < width) this->setSize(width, this->size().y);

		/////////////////////////////////////////////////////////////////////
		/////////	COUNTING ALL CHILDREN
		FOR_VEC_I(it, m_children, C_Widget*)
		{
			C_Widget* w = (*it);
			if (w->getVisible() == false) continue;
			float leftSpace = 0.0f;
			/////////////////////////////////////////////////////////////////////
			/////////	LEFT
			if (m_hAlign == GRID_LEFT)
			{
				leftSpace += m_margin.r;
			}
			/////////////////////////////////////////////////////////////////////
			/////////	CENTER
			else if (m_hAlign == GRID_CENTER)
			{
				leftSpace += (this->size().x / 2.0f) - (w->size().x / 2.0f);
			}
			/////////////////////////////////////////////////////////////////////
			/////////	RIGHT
			else if (m_hAlign == GRID_RIGHT)
			{
				leftSpace += this->size().x - w->size().x - m_margin.g;
			}
			w->setPos(leftSpace, w->pos().y);
		}
	}
	else if (m_containerType == CONTAINER_HORIZONTAL)
	{
		float width = m_margin.r + this->getMaxWidgetWidth() + m_margin.g;
		//if widget size is less than embedded widgets
		if (this->size().x < width) this->setSize(width, this->size().y);


		float leftSpace = 0;
		/////////////////////////////////////////////////////////////////////
		/////////	MIDDLE
		if (m_vAlign == GRID_CENTER)
		{
			leftSpace = (this->size().x / 2.0f) - (width / 2.0f);
		}
		/////////////////////////////////////////////////////////////////////
		/////////	BOTTOM
		else if (m_vAlign == GRID_RIGHT)
		{
			leftSpace = this->size().x - width;
		}
		/////////////////////////////////////////////////////////////////////
		/////////	TOP
		else if (m_vAlign == GRID_LEFT)
		{
			leftSpace += m_margin.r;
		}


		/////////////////////////////////////////////////////////////////////
		/////////	COUNTING ALL CHILDREN
		FOR_VEC_I(it, m_children, C_Widget*)
		{
			C_Widget* w = (*it);
			if (w->getVisible() == false) continue;

			w->setPos(leftSpace, w->pos().y);
			leftSpace += w->size().x + ((it + 1 != m_children.end()) ? m_padding : 0.0f); //width + padding
		}
	}
}

/////////////////////////////////////////////////////////////////////////////////////////////
//	ALL CHILDREN UPDATE Y
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::updateY()
{
	if (m_containerType == CONTAINER_VERTICAL)
	{
		float height = m_margin.b + this->getWidgetsHeight() + m_margin.a;
		//if widget size is less than embedded widgets
		if (this->size().y < height) this->setSize(this->size().x, height);


		float topSpace = 0;
		/////////////////////////////////////////////////////////////////////
		/////////	MIDDLE
		if (m_vAlign == GRID_MIDDLE)
		{
			topSpace = (this->size().y / 2.0f) - (height / 2.0f);
		}
		/////////////////////////////////////////////////////////////////////
		/////////	BOTTOM
		else if (m_vAlign == GRID_BOTTOM)
		{
			topSpace = this->size().y - height - m_margin.a;
		}
		/////////////////////////////////////////////////////////////////////
		/////////	TOP
		else if (m_vAlign == GRID_TOP)
		{
			topSpace += m_margin.b;
		}


		/////////////////////////////////////////////////////////////////////
		/////////	COUNTING ALL CHILDREN
		FOR_VEC_I(it, m_children, C_Widget*)
		{
			C_Widget* w = (*it);
			if (w->getVisible() == false) continue;
			w->setPos(w->pos().x, topSpace);
			topSpace += w->size().y + ((it + 1 != m_children.end()) ? m_padding : 0.0f); //height + padding
		}
	}
	else if (m_containerType == CONTAINER_HORIZONTAL)
	{
		float height = m_margin.b + this->getMaxWidgetHeight() + m_margin.a;
		if (this->size().y < height) this->setSize(this->size().x, height);

		/////////////////////////////////////////////////////////////////////
		/////////	COUNTING ALL CHILDREN
		FOR_VEC_I(it, m_children, C_Widget*)
		{
			C_Widget* w = (*it);
			if (w->getVisible() == false) continue;
			float topSpace = 0.0f;
			/////////////////////////////////////////////////////////////////////
			/////////	LEFT
			if (m_vAlign == GRID_TOP)
			{
				topSpace += m_margin.b;
			}
			/////////////////////////////////////////////////////////////////////
			/////////	CENTER
			else if (m_vAlign == GRID_MIDDLE)
			{
				topSpace += (this->size().y / 2.0f) - (w->size().y / 2.0f);
			}
			/////////////////////////////////////////////////////////////////////
			/////////	RIGHT
			else if (m_vAlign == GRID_BOTTOM)
			{
				topSpace += this->size().y - w->size().y - m_margin.a;
			}
			w->setPos(w->pos().x, topSpace);
		}
	}
}

/////////////////////////////////////////////////////////////////////////////////////////////
//	ON CLICK BUTTON
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::onClickButton(sf::Mouse::Button b_type)
{
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	ON PRESS BUTTON
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::onPressButton(sf::Mouse::Button b_type)
{
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	ON RELEASE BUTTON
/////////////////////////////////////////////////////////////////////////////////////////////
void C_Widget::onReleaseButton(sf::Mouse::Button b_type)
{

}


/////////////////////////////////////////////////////////////////////////////////////////////
//	GET WIDGETS WIDTH
/////////////////////////////////////////////////////////////////////////////////////////////
float C_Widget::getWidgetsWidth()
{
	float width = m_margin.r; //margin left

	FOR_VEC_I(it, m_children, C_Widget*)
	{
		if ((*it)->getVisible() == false) continue;
		width += (*it)->size().x + ((it+1 != m_children.end()) ? m_padding : 0.0f);
	}

	width += m_margin.g; // +margin right
	return width;
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	GET WIDTH HEIGHT
/////////////////////////////////////////////////////////////////////////////////////////////
float C_Widget::getWidgetsHeight()
{
	float height = m_margin.b; //margin top

	FOR_VEC_I(it, m_children, C_Widget*)
	{
		if ((*it)->getVisible() == false) continue;
		height += (*it)->size().y + ((it + 1 != m_children.end()) ? m_padding : 0.0f);
	}

	height += m_margin.a; // +margin bottom
	return height;
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	GET MAX WIDGET WIDTH
/////////////////////////////////////////////////////////////////////////////////////////////
float C_Widget::getMaxWidgetWidth()
{
	if (m_children.size() == 0) return 0.0f;
	float width = m_children[0]->size().x;
	FOR_VEC_I(it, m_children, C_Widget*)
	{
		if ((*it)->getVisible() == false) continue;
		if (width < (*it)->size().x)
		{
			width = (*it)->size().x;
		}
	}

	return width;
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	GET MAX WIDGET HEIGHT
/////////////////////////////////////////////////////////////////////////////////////////////
float C_Widget::getMaxWidgetHeight()
{
	if (m_children.size() == 0) return 0.0f;

	float height = m_children[0]->size().y;
	FOR_VEC_I(it, m_children, C_Widget*)
	{
		if ((*it)->getVisible() == false) continue;
		if (height < (*it)->size().y)
		{
			height = (*it)->size().y;
		}
	}

	return height;
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	GET MIN WIDGET WIDTH
/////////////////////////////////////////////////////////////////////////////////////////////
float C_Widget::getMinWidgetWidth()
{
	if (m_children.size() == 0) return 0.0f;
	float width = m_children[0]->size().x;
	FOR_VEC_I(it, m_children, C_Widget*)
	{
		if ((*it)->getVisible() == false) continue;
		if (width > (*it)->size().x)
		{
			width = (*it)->size().x;
		}
	}

	return width;
}


/////////////////////////////////////////////////////////////////////////////////////////////
//	GET MIN WIDGET HEIGHT
/////////////////////////////////////////////////////////////////////////////////////////////
float C_Widget::getMinWidgetHeight()
{
	if (m_children.size() == 0) return 0.0f;

	float height = m_children[0]->size().y;
	FOR_VEC_I(it, m_children, C_Widget*)
	{
		if ((*it)->getVisible() == false) continue;
		if (height > (*it)->size().y)
		{
			height = (*it)->size().y;
		}
	}

	return height;
}

void C_Widget::syncWidgets()
{
	///////////////////////////////////////////////////////////////
	////////////	FOR SYNCHRONIZATION WITH POSITION
}